using System.Diagnostics;
using EnvDTE;

namespace Microsoft.WowAddonStudio.Tests.Common.Mocks
{
	/// <summary>
	/// Represents, as a single transaction, all operations performed on all participating open 
	/// documents in Visual Studio. If its EnvDTE.UndoContext.SetAborted() method is invoked, 
	/// all changes made since opening the object are discarded.
	/// </summary>
	public class MockUndoContext : UndoContext
	{
		private const string objectName = "MockUndoContext";
		private string contextName;

		/// <summary>
		/// Initializes a new instance of the <see cref="MockUndoContext"/> class.
		/// </summary>
		/// <param name="dte">The DTE.</param>
		public MockUndoContext(DTE dte)
		{
			DTE = dte;
		}

		#region UndoContext Members

		/// <summary>
		/// Starts a new undo operation.
		/// </summary>
		/// <param name="Name">Required. Represents the name of the procedure for which to provide an undo context.</param>
		/// <param name="Strict">Optional. Indicates whether the undo stack linkage is strict. Default value is False.</param>
		public void Open(string Name, bool Strict)
		{
			IsStrict = Strict;
			IsAborted = false;
			contextName = Name;
			Trace.WriteLine(string.Concat(objectName, " Open: ", contextName));
		}

		/// <summary>
		/// Ends an undo operation.
		/// </summary>
		public void Close()
		{
			Trace.WriteLine(string.Concat(objectName, " Close: ", contextName));
			contextName = string.Empty;
		}

		/// <summary>
		/// Discards all changes to participating open documents since opening the <see cref="T:EnvDTE.UndoContext"/> object.
		/// </summary>
		public void SetAborted()
		{
			IsAborted = true;
		}

		/// <summary>
		/// Gets the top-level extensibility object.
		/// </summary>
		/// <value></value>
		/// <returns>A <see cref="T:EnvDTE.DTE"/> object.</returns>
		public DTE DTE { get; private set; }

		/// <summary>
		/// Gets the immediate parent object of an <see cref="T:EnvDTE.UndoContext"/> object.
		/// </summary>
		/// <value></value>
		/// <returns>A <see cref="T:EnvDTE.DTE"/> object.</returns>
		public DTE Parent
		{
			get { return DTE; }
		}

		/// <summary>
		/// Gets whether the undo stack linkage is strict.
		/// </summary>
		/// <value></value>
		/// <returns>A Boolean value indicating true if the undo stack linkage is set to strict, false if not.</returns>
		public bool IsStrict { get; private set; }

		/// <summary>
		/// Gets whether the <see cref="T:EnvDTE.UndoContext"/> object operation was terminated by the <see cref="M:EnvDTE.UndoContext.SetAborted"/> method.
		/// </summary>
		/// <value></value>
		/// <returns>A Boolean value indicating true if the operation was aborted, false if not.</returns>
		public bool IsAborted { get; private set; }

		/// <summary>
		/// Gets whether an undo operation is currently in effect or if a solution is open.
		/// </summary>
		/// <value></value>
		/// <returns>A Boolean value indicating true if an undo operation is in effect or if a solution is open, false if not.</returns>
		public bool IsOpen
		{
			get { return !string.IsNullOrEmpty(contextName); }
		}

		#endregion
	}
}